package com.rpgfw.graphics;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;

public class PixelImage implements DrawGraphics{
    //存着除了颜色列表之外的位数据
    char bitMap[][];
    //颜色列表
    HashMap<Character, Color>  colorList=new HashMap<Character,Color>();
    //image尺寸
    Dimension size=new Dimension(0,0);
    //生成的image
    BufferedImage img;
    //PixelGraphics
    PixelGraphics graphics=new PixelGraphics(this);
    //当前选择的color
    char clNow='0';
    //字符映射表
    char symbol[]=new char[]{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    public PixelImage(String code){
        //this.img=new BufferedImage((int)size.getWidth(),(int)size.getHeight(),BufferedImage.TYPE_INT_ARGB);
        //this.bitMap=new char[(int)size.getHeight()][(int)size.getWidth()];
        //this.size.setSize();
        decodeCode(code);
    }
    public PixelImage(int width,int height){
        //this.img=new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
        this.bitMap=new char[height][width];
        initBitMap();
        this.size.setSize(width, height);
    }
    /*
    public PixelImage(int width,int height,int type){
        //this.img=new BufferedImage(width,height,type);
        this.bitMap=new char[height][width];
    }

     */
    public void initBitMap(){
        for(int i=0;i<bitMap.length;i++){
            for(int j=0;j<bitMap[0].length;j++){
                bitMap[i][j]='T';
            }
        }
    }
    /*
    * 解码存入
    * */
    public void decodeCode(String code){
        String spl[]=code.split(";");
        int len=spl.length;
        //读取尺寸
        this.size.setSize(Integer.parseInt(spl[0]),Integer.parseInt(spl[1]));
        this.bitMap=new char[(int)size.getHeight()][(int)size.getWidth()];
        initBitMap();
        //读取所有颜色
        for(int i=2;i<len-1;i++){
            String clCode=spl[i];
            colorList.put(clCode.toCharArray()[0],new Color(Integer.parseInt(clCode.substring(1))));
        }
        //读取位数据
        //this.bitMap=new String(spl[len-1]);
        char bit[]=spl[len-1].toCharArray();
        int index=0;
        lineLoop:for(int i=0;i<this.size.getHeight();i++){
            rowLoop:for(int j=0;j<this.size.getWidth();j++){
                try {
                    switch(bit[index]){
                        case 'L':{//换行
                            continue lineLoop;
                        }
                        case 'E':{//结束
                            break lineLoop;
                        }
                        case 'T':{//无（透明）
                            break;
                        }
                        default:{
                            this.bitMap[i][j] = bit[index];
                        }
                    }
                }catch(Exception e){

                }
                index++;
            }
        }
    }

    /*
    * 指定格子的宽高以渲染
    * */
    public void render(int gridWidth,int gridHeight){
        this.img=new BufferedImage((int)(gridWidth*this.size.getWidth()),(int)(gridHeight*this.size.getHeight()),BufferedImage.TYPE_INT_ARGB);
        Graphics g=img.createGraphics();
        //挨个格子渲染
        for(int i=0;i<this.size.getHeight();i++){
            for(int j=0;j<this.size.getWidth();j++){
                if(this.bitMap[i][j]=='T'){
                    //System.out.print(1);
                    continue;
                }
                g.setColor(this.colorList.get(this.bitMap[i][j]));
                g.fillRect(j*gridWidth,i*gridHeight,gridWidth,gridHeight);
            }
        }
        //渲染完毕后检查没有被引用的颜色并删除
        deleteUnusedColor();
    }

    public char addColor(Color color){
        for(char sym:this.colorList.keySet()){
            //是否已经存在了
            if(colorList.get(sym).getRGB()==color.getRGB()){
                return sym;
            }
        }
        //没有存在,遍历取得可用的sym
        for(char sym:this.symbol){
            if(!this.colorList.keySet().contains(sym)){//找到一个现在colorlist未使用的symbol
                this.colorList.put(sym,color);
                return sym;
            }
        }
        //已经没有可用的颜色符号了
        return 'N';
    }
    /*
    * 删除没有被用到的颜色
    * */
    public void deleteUnusedColor(){
        ArrayList<Character> usedClSym=new ArrayList<Character>();//这里保存了已使用的颜色符号
        //遍历所有格子
        for(int i=0;i<this.size.getHeight();i++){
            for(int j=0;j<this.size.getWidth();j++){
                usedClSym.add(this.bitMap[i][j]);
            }
        }
        //检查colorList里每个符号是否都被使用了
        ArrayList<Character> symToRemove=new ArrayList<Character>();//要被删除的符号
        for(char sym:colorList.keySet()){
            if(!usedClSym.contains(sym)){//已使用的符号中不包含正在被遍历的符号
                symToRemove.add(sym);
            }
        }
        //挨个删除
        for(char symrem:symToRemove){
            this.colorList.remove(symrem);
        }
    }
    /*
    *将存入的数据编码
    */
    public String  encodeImage(){
        StringBuffer result=new StringBuffer("");
        //打包尺寸
        result.append((int)size.getWidth()+";"+(int)size.getHeight()+";");
        //打包颜色列表
        for(char key:this.colorList.keySet()){
            //第一个字符是symbol
            //sym和rgb之间无分隔符
            result.append(key+""+this.colorList.get(key).getRGB()+";");
        }
        //打包位数据
        //result.append(this.bitMap);
        for(int i=0;i<size.getHeight();i++){
            for(int j=0;j<this.size.getWidth();j++){
                result.append(this.bitMap[i][j]);
            }
        }
        return result.toString();
    }

    /*
    * 如果从未渲染，则会返回null
    * */
    public Image getImage(){
        return img;
    }
    public BufferedImage getBufferedImage(){
        return img;
    }

    /*
    * 给定格子宽高以渲染并返回最新img
    * */
    public Image getImage(int gridWidth,int gridHeight){
        render(gridWidth, gridHeight);
        return getImage();
    }
    public PixelGraphics getPixelGraphics(){
        return this.graphics;
    }

    public int getWidth(){
        return (int)this.size.getWidth();
    }
    public int getHeight(){
        return (int)this.size.getHeight();
    }
    public Color getColor(char symbol){
        return this.colorList.get(symbol);
    }
    @Override
    public void drawDot(int x, int y) {
        char clSym=this.clNow;
        if(clSym=='N'){
            System.out.println("Error:cannot use this color to paint:No symbol can be used to index color.\\paint failed.");
            return;
        }
        try {
            this.bitMap[y][x] = clSym;
        }catch(Exception e){

        }
    }
    @Override
    public void changeColor(Color color){
        this.clNow=this.addColor(color);
    }
}
